package com.bsj.sipgateway.web.controller;

import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSON;
import com.bsj.power.common.config.exception.ApiException;
import com.bsj.power.common.config.global.JsonResult;
import com.bsj.power.common.config.global.JsonResultEnum;
import com.bsj.power.common.config.global.TokenUser;
import com.bsj.power.common.config.redis.RedisConstant;
import com.bsj.power.common.mapper.UserRoleMapper;
import com.bsj.power.common.util.StpLoginUserUtil;
import com.bsj.power.common.util.StringUtils;
import com.bsj.sipgateway.sip.transmit.cmd.impl.SIPCommander;
import com.bsj.sipgateway.util.RedisDeviceInfoUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import redis.clients.bsj.JedisClusterBSJ;

import javax.annotation.Resource;
import javax.sip.InvalidArgumentException;
import javax.sip.SipException;
import java.text.ParseException;

/**
 * @Description 设备控制
 * @menu 设备控制
 * @Author zhaoyang
 * @Date 2024/4/25 10:58
 */
@RestController
@RequestMapping(value = "/api/control")
@Slf4j
//@SaCheckPermission("/video/api/control")
public class ApiControlController {

    @Autowired
    private SIPCommander sipCommander;

    @Resource
    private UserRoleMapper userRoleMapper;

    @Autowired
    private JedisClusterBSJ jedisClusterBSJ;

    @Autowired
    private RedisDeviceInfoUtil redisDeviceInfoUtil;

    /**
     * 设备控制 - 预置位控制
     *
     * @param deviceId      设备国标id
     * @param channelSerial 通道序号, 默认值: 1
     * @param command       控制指令 允许值: set, goto, remove
     * @param preset        预置位编号(1~255)
     * @param name          预置位名称, command=set 时有效
     * @return
     */
    @GetMapping(value = "/preset")
    private void preset(String deviceId, String command,
                        @RequestParam(required = false) Integer channelSerial,
                        @RequestParam(required = false) String name,
                        @RequestParam(required = false) Integer preset) {

        log.debug("模拟接口> 预置位控制 API调用，deviceId：{} ，channelId：{} ，command：{} ，name：{} ，preset：{} ",
                deviceId, channelSerial, command, name, preset);

        if (channelSerial == null) {
            channelSerial = 1;
        }
        // 指令码
        int cmdCode = 0;
        switch (command) {
            case "set":
                cmdCode = 129;
                break;
            case "goto":
                cmdCode = 130;
                break;
            case "remove":
                cmdCode = 131;
                break;
            default:
                break;
        }
        try {
            sipCommander.frontEndCmd(deviceId, channelSerial, cmdCode, 0, preset, 0);
        } catch (SipException | InvalidArgumentException | ParseException e) {
            log.error("[命令发送失败] 预置位控制: {}", e.getMessage());
            throw new ApiException(JsonResultEnum.FAIL);
        }
    }


    /**
     * 设备云台控制
     *
     * @param deviceId      设备id
     * @param command       控制命令
     * @param channelSerial 逻辑通道号 默认是1
     * @return: void
     * @decription 设备云台控制
     * @author zhaoyang
     * @date 2024/4/29 15:37
     */
    @RequestMapping(value = "/ptzControl")
    public JsonResult ptzControl(@RequestParam String deviceId, @RequestParam String command, @RequestParam Integer moveSpeed, @RequestParam(required = false) Integer channelSerial) {
        if (channelSerial == null) {
            // 默认使用逻辑通道1
            channelSerial = 1;
        }
        if (moveSpeed == null) {
            moveSpeed = 50; // 默认值50
        }
//        TokenUser tokenUser = StpLoginUserUtil.getTokenUser();
//        if (tokenUser == null) {
//            throw new RuntimeException("无法获取登录用户信息，请重试");
//        }
//        Long tokenUserUserId = tokenUser.getUserId();
//        Integer roleType = userRoleMapper.selectUserRoleType(tokenUserUserId);
//        Integer loginUserWeight = tokenUser.getUserWeight();
//        String lockedStr = redisDeviceInfoUtil.getPtzControlLock(deviceId);
        // 如果没锁定并且锁定的权重比登录的权重大，就是没权限操作
        // 这里不处理了，交给前端处理
//        if (lockedStr != null && Integer.parseInt(lockedStr) > loginUserWeight) {
//            throw new RuntimeException("云台操作权限不足，请联系管理员修改");
//        }

        sipCommander.ptz(command, moveSpeed, deviceId, channelSerial);
        return JsonResult.success();
    }

    /**
     * 云台锁定
     *
     * @param deviceId 设备国标编号
     * @param type     1锁定2解锁
     * @return
     */
    @RequestMapping("/ptzControlLock")
    public JsonResult ptzControlLock(@RequestParam String deviceId, @RequestParam Integer type) {
        TokenUser tokenUser = StpLoginUserUtil.getTokenUser();
        if (tokenUser == null) {
            throw new ApiException(JsonResultEnum.USER_INFO_ISNULL);
        }
        Integer userWeight = tokenUser.getUserWeight(); // 用户云台操作权重
        Long userId = tokenUser.getUserId();
        if (userId == null || userWeight == null) {
            throw new ApiException(JsonResultEnum.FAIL, "用户id或用户权重为空，无法操作");
        }
        log.info("获取到的用户的权重信息是userWeight={}，锁定的用户id={}", userWeight, userId);
        if (type == 1) {
            jedisClusterBSJ.set(RedisConstant.PTZ_CONTROL_LOCK + deviceId, userId + "_" + userWeight);
        } else if (type == 2) {
            jedisClusterBSJ.del(RedisConstant.PTZ_CONTROL_LOCK + deviceId);
        }
        return JsonResult.success();
    }


    /**
     * 远程启动控制命令
     *
     * @param deviceId
     * @return: void
     * @decription 远程启动控制命令
     * @author zhaoyang
     * @date 2024/5/30 16:58
     */
    @RequestMapping("/teleboot")
    public void teleBootApi(@RequestParam String deviceId) {
        sipCommander.teleBootCmd(deviceId);

    }


    /**
     * @param deviceId  设备国标id
     * @param guardType 布防撤防类型 1布防 0撤防
     * @return: void
     * @decription
     * @author zhaoyang
     * @date 2024/6/27 10:29
     */
    @RequestMapping("/guardApi")
    public void guardApi(@RequestParam String deviceId, @RequestParam Integer guardType) {
        // 命令， 可选值：SetGuard（布防），ResetGuard（撤防）
        String guardCmdStr = null;
        if (guardType == null || guardType == 0) {
            guardCmdStr = "ResetGuard";
        } else if (guardType == 1) {
            guardCmdStr = "SetGuard";
        }
        sipCommander.guardCmd(deviceId, guardCmdStr);

    }

    /**
     * 回放暂停
     *
     * @param did
     * @param channelSerial
     */
    @RequestMapping("/playPauseCmd")
    public JsonResult playPauseCmd(Long did, Integer channelSerial) {
        sipCommander.playPauseCmd(did, channelSerial);
        return JsonResult.success();
    }

    /**
     * 回放恢复
     *
     * @param did
     * @param channelSerial
     */
    @RequestMapping("/playResumeCmd")
    public JsonResult playResumeCmd(Long did, Integer channelSerial) {
        sipCommander.playResumeCmd(did, channelSerial);
        return JsonResult.success();

    }


    /**
     * 倍速/快放慢放
     *
     * @param did
     * @param channelSerial
     * @param speed
     */
    @RequestMapping("/playSpeedCmd")
    public JsonResult playSpeedCmd(Long did, Integer channelSerial, Double speed) {
        if (speed != 0.25 && speed != 0.5 && speed != 1 && speed != 2.0 && speed != 4.0) { //暂时只支持这几种
            log.warn("不支持的speed： " + speed);
            throw new ApiException(JsonResultEnum.ERROR100);
        }
        if (channelSerial == null) {
            channelSerial = 1;
        }
        sipCommander.playSpeedCmd(did, channelSerial, speed);
        return JsonResult.success();
    }

    /**
     * @param did
     * @param recordCmdStr  录像命令：Record / StopRecord
     * @param channelSerial
     */
    @RequestMapping("/recordCmd")
    public JsonResult recordCmd(Long did, String recordCmdStr, Integer channelSerial) {
        if (StringUtils.isEmpty(recordCmdStr) || (!"Record".equals(recordCmdStr) && !"StopRecord".equals(recordCmdStr))) {
            throw new ApiException(JsonResultEnum.PARAM_ERROR);
        }
        sipCommander.recordCmd(did, recordCmdStr, channelSerial);
        return JsonResult.success();

    }

    @Value("${aiDefenseUrl}")
    String aiDefenseUrl;


    /**
     * ai报警布防/撤防
     *
     * @param devId
     * @param changer
     * @return
     */
    @GetMapping("/aiDefense")
    public JsonResult aiDefense(@RequestParam("devId") Long devId, @RequestParam("changer") String changer) {
        String result = HttpRequest.get(aiDefenseUrl + "?devId=" + devId + "&changer=" + changer)
                .header("content-type", "application/json")
//                .header("Tenant", "1469181295663300608")
//                .header("Authorization", getAuthorization(accessToken))
                .execute().body();
        log.info("ai布防撤防详情:{}", result);
        log.info("调用ai布防接口成功，devId={}, changer={}", devId, changer);
        return JSON.parseObject(result, JsonResult.class);
    }


}
